package org.streets.eis;

import org.apache.wicket.Application;
import org.apache.wicket.Component;
import org.apache.wicket.Page;
import org.apache.wicket.Request;
import org.apache.wicket.Response;
import org.apache.wicket.RestartResponseAtInterceptPageException;
import org.apache.wicket.Session;
import org.apache.wicket.authorization.IUnauthorizedComponentInstantiationListener;
import org.apache.wicket.protocol.http.WebRequest;
import org.apache.wicket.protocol.http.WebResponse;
import org.apache.wicket.request.target.coding.HybridUrlCodingStrategy;
import org.apache.wicket.settings.IExceptionSettings;
import org.apache.wicket.util.convert.ConverterLocator;
import org.apache.wicket.util.time.Duration;
import org.streets.wicket.HiveWebApplication;
import org.streets.wicket.HiveWicketException;

import org.streets.eis.setting.auth.UserPermitAuthorizer;
import org.streets.eis.setting.auth.UserPermitStrategy;
import org.streets.eis.entity.User;
import org.streets.eis.setting.converters.BoolConverter;
import org.streets.eis.setting.converters.SqlDateConverter;
import org.streets.eis.setting.converters.SqlTimeConverter;
import org.streets.eis.setting.converters.SqlTimestampConverter;
import org.streets.eis.setting.converters.StringConverter;


public abstract class EisApplication extends HiveWebApplication {
	
	public static EisApplication get() {
		
		Application application = Application.get();

		if (!(application instanceof EisApplication)) {
			throw new HiveWicketException("The application attached to the current thread is not a " +
					EisApplication.class.getSimpleName());
		}
		return (EisApplication)application;
	}	

	
	@Override
	public void init() {
		
		super.init();
		
		ConverterLocator converters = (ConverterLocator) getConverterLocator();
		converters.set(java.sql.Date.class, new SqlDateConverter());
		converters.set(java.sql.Time.class, new SqlTimeConverter());		
		converters.set(java.sql.Timestamp.class, new SqlTimestampConverter());
		converters.set(String.class, new StringConverter());
		converters.set(Boolean.class, BoolConverter.INSTANCE);

		String configurationType = getConfigurationType();
		if (DEVELOPMENT.equalsIgnoreCase(configurationType)) {
			getResourceSettings().setThrowExceptionOnMissingResource(true);
			getResourceSettings().setResourcePollFrequency(Duration.ONE_SECOND);
			getDebugSettings().setComponentUseCheck(true);
			getMarkupSettings().setStripWicketTags(true);
			getExceptionSettings().setUnexpectedExceptionDisplay(IExceptionSettings.SHOW_EXCEPTION_PAGE);
			getDebugSettings().setAjaxDebugModeEnabled(true);
		} else if (DEPLOYMENT.equalsIgnoreCase(configurationType)) {
			getResourceSettings().setThrowExceptionOnMissingResource(false);
			getResourceSettings().setResourcePollFrequency(null);
			getDebugSettings().setComponentUseCheck(false);
			getMarkupSettings().setStripWicketTags(true);
			getExceptionSettings().setUnexpectedExceptionDisplay(IExceptionSettings.SHOW_INTERNAL_ERROR_PAGE);
			getDebugSettings().setAjaxDebugModeEnabled(false);
		}
		//获取框架的验证器
		UserPermitAuthorizer authorizer = registry.service(UserPermitAuthorizer.class);
		getSecuritySettings().setAuthorizationStrategy(new UserPermitStrategy(authorizer));
		getSecuritySettings().setUnauthorizedComponentInstantiationListener(
				new IUnauthorizedComponentInstantiationListener() {
					//如果没有认证的页面 登录了就导向至没有权限页面，没有登录就导向至登录页面
					public void onUnauthorizedInstantiation(Component component) {
						User user = EisWebSession.get().getUser();
						if (user == null) {
							throw new RestartResponseAtInterceptPageException(getLoginPage());
						} else {
							throw new RestartResponseAtInterceptPageException(EisApplication.get().getApplicationSettings().getAccessDeniedPage());							
						}						
					}					
				}
		);
		
		mount(new HybridUrlCodingStrategy("/home", getHomePage()));
		mount(new HybridUrlCodingStrategy("/login",getLoginPage()));		
		
	}
	
	@Override
	public Session newSession(Request request, Response response) {
		return new EisWebSession(request);
	}
    
    @Override
    public EisRequestCycle newRequestCycle(final Request request, final Response response) {
    	// EisRequestCycle provide SQLTransaction auto management
    	return new EisRequestCycle(this, (WebRequest)request, (WebResponse)response);
    }
    
	/**
	 * A eis application must supply a login page, if the login location to homepage, then login page is HomePage too.
	 * @return
	 */
	public abstract Class<? extends Page> getLoginPage();

}
